#include "voiceclient.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLabel>

VoiceClient::VoiceClient(QWidget *parent) : QWidget(parent), isCalling(false) {
    // UI Setup
    QVBoxLayout *layout = new QVBoxLayout(this);

//    QHBoxLayout *ipLayout = new QHBoxLayout();
//    ipLayout->addWidget(new QLabel("Server IP:"));
//    serverIPEdit = new QLineEdit("192.168.248.128");
//    ipLayout->addWidget(serverIPEdit);

//    QHBoxLayout *portLayout = new QHBoxLayout();
//    portLayout->addWidget(new QLabel("Port:"));
//    serverPortEdit = new QLineEdit("7777");
//    portLayout->addWidget(serverPortEdit);

    callButton = new QPushButton("Start Call");

//    layout->addLayout(ipLayout);
//    layout->addLayout(portLayout);
    layout->addWidget(callButton);

    connect(callButton, &QPushButton::clicked, this, &VoiceClient::toggleCall);

    // Network
    udpSocket = new QUdpSocket(this);

    // Audio Format
    format.setSampleRate(44100);
    format.setChannelCount(1);
    format.setSampleSize(16);
    format.setCodec("audio/pcm");
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setSampleType(QAudioFormat::SignedInt);

    //toggleCall();
}

void VoiceClient::initAudio() {
    audioInput = new QAudioInput(format, this);
    audioOutput = new QAudioOutput(format, this);

    connect(audioInput, &QAudioInput::stateChanged, this, &VoiceClient::handleStateChanged);
    connect(audioOutput, &QAudioOutput::stateChanged, this, &VoiceClient::handleStateChanged);
}

void VoiceClient::toggleCall() {
    if (!isCalling) {
        startCall();
    } else {
        stopCall();
    }
}

void VoiceClient::startCall() {
    initAudio();

    // Start audio input
    inputDevice = audioInput->start();
    connect(inputDevice, &QIODevice::readyRead, [=]() {
        QByteArray data = inputDevice->readAll();
        udpSocket->writeDatagram(data, QHostAddress("120.26.230.219"),
                               8888);
    });

    // Start audio output
    outputDevice = audioOutput->start();

    // Setup UDP receiver
    connect(udpSocket, &QUdpSocket::readyRead, this, &VoiceClient::readPendingDatagrams);

    callButton->setText("Stop Call");
    isCalling = true;
}

void VoiceClient::stopCall() {
    audioInput->stop();
    audioOutput->stop();
    delete audioInput;
    delete audioOutput;
    udpSocket->close();

    callButton->setText("Start Call");
    isCalling = false;
}

void VoiceClient::readPendingDatagrams() {
    while (udpSocket->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());
        udpSocket->readDatagram(datagram.data(), datagram.size());
        outputDevice->write(datagram);
    }
}

void VoiceClient::handleStateChanged(QAudio::State state) {
    if (state == QAudio::StoppedState) {
        QAudio::Error error = (sender() == audioInput) ?
                            audioInput->error() : audioOutput->error();
        if (error != QAudio::NoError) {
            stopCall();
        }
    }
}

